<script setup lang="ts">
import {ref, onMounted} from 'vue';
// import * as groupApi from '@/api/SysGroupApi'
import * as apiUtil from '@/api/ApiUtils'
import {SelectOption} from "@/ts/CommonTypes";
import * as api from "@/api/CodeGenerator";
import {TemplateVO, TableColumnVO,RunLog,CodeContentVO,FileVO} from "@/api/CodeGenerator";

import IconSelector from "@/components/IconSelector.vue";

// 文档 https://imzbf.github.io/md-editor-v3/zh-CN/api
import {MdEditor, MdPreview, MdCatalog} from 'md-editor-v3';
import 'md-editor-v3/lib/style.css';
import Template from "@/views/Template.vue";


onMounted(() => {
  // 获取分组选项
  // groupApi.getOptions("Menu").then((res) => {
  //   if (apiUtil.isSuccessed(res)) {
  //     groupTree.value = res.data || []
  //   }
  // });
  api.getAllTables().then(res => {
    if (apiUtil.isSuccessed(res)) {
      tableList.value = res.data;
    }
  })
})

const handleQueryTables = (tableName: string) => {
  api.getColumnList(tableName).then(res => {
    if (apiUtil.isSuccessed(res)) {
      vo.value = res.data;
    }
  })
}

const handleIconChanged = (name: string) => {
  vo.value.iconName = name
}

const newColumns = ref<[]>([]);

const columns = [
  {
    title: "数据库",
    children: [
      {title: '字段名', dataIndex: 'name', key: 'name'},
      {title: '字段类型', dataIndex: 'type', key: 'type'},
      {title: '必填字段', dataIndex: 'required', key: 'required'},
      {title: '注释', dataIndex: 'comment', key: 'comment', width: 100, ellipsis: true}
    ]
  },
  {
    title: "Java",
    children: [
      {title: 'Java字段名', dataIndex: 'javaName', key: 'javaName'},
      {title: 'Java字段类型', dataIndex: 'javaType', key: 'javaType'}
    ]
  },
  {
    title: "TypeScript",
    children: [
      {title: 'TypeScript字段名', dataIndex: 'javaName', key: 'tsName'},
      {title: 'TypeScript字段类型', dataIndex: 'tsType', key: 'tsType'}
    ]
  },
  {
    title: "Vue",
    children: [
      {title: '表格中是否展示', dataIndex: 'isTableColumn', key: 'isTableColumn'},
      {title: '表格中展示标题', dataIndex: 'columnTitle', key: 'columnTitle', width: 150},
      {title: '表单中是否展示', dataIndex: 'isFormData', key: 'isFormData'},
      {title: '表单中必填', dataIndex: 'formNotNull', key: 'formNotNull'}
    ]
  }
];



const vo = ref<TemplateVO>(new TemplateVO());
const groupTree = ref<any[]>([]);
const tableList = ref<SelectOption[]>([]);
const scrollElement = document.documentElement;


/**
 * "selectTable"|
 *     "editConfig"|
 *     "previewCode"
 */
const stepActive = ref<string[]>(["selectTable"]);

const activeKey = ref<"table" | "java" | "value">("table");

const checkboxOptions = [
  {label: '后端代码(Java)', value: 'java'},
  {label: '前端代码(Vue3 + TypeScript)', value: 'vue'},
  {label: '菜单(MySQL)', value: 'menu'},
];

// 存储用户选择的文件夹句柄
const javaDirHandle = ref<FileSystemDirectoryHandle | null>(null);
const javaPath = ref<string>('');

const vueDirHandle = ref<FileSystemDirectoryHandle | null>(null);
const vuePath = ref<string>('');


const resultMessage = ref<string>('');
const menuConfigFlag = ref<'disabled' | null>('disabled');

// 1. 用户选择项目文件夹，并保存其句柄
async function selectFolder(packageType:'java'|'vue') {
  try {
    const dirHandle = await window.showDirectoryPicker();
    if(packageType === 'java'){
      javaDirHandle.value = dirHandle;
      javaPath.value = dirHandle.name;
    }else {
      vueDirHandle.value = dirHandle;
      vuePath.value = dirHandle.name;
    }
    resultMessage.value = '已选择文件夹';
  } catch (error) {
    console.error('选择失败:', error);
    resultMessage.value = '选择失败，请查看控制台日志';
  }
}

 async function createAll(){
  if(javaDirHandle.value && codeContent.value.javaFiles){
    await createContent(javaDirHandle.value,codeContent.value.javaFiles);
  }
  if(vueDirHandle.value && codeContent.value.vueFiles){
    await createContent(vueDirHandle.value,codeContent.value.vueFiles);
  }
}

// 2. 创建子文件夹和文件（基于已选文件夹）
async function createContent(dirHandle: FileSystemDirectoryHandle,files:FileVO[]) {
  if (!dirHandle) return;

  for (let file of files) {
    try {
      const newFolderPath = file.projectPath; // 支持多级目录
      const folderNames = newFolderPath.split('/').filter((name: string) => name);

      let currentDir = dirHandle;
      for (const name of folderNames) {
        try {
          // 检查是否已经存在该目录
          currentDir = await currentDir.getDirectoryHandle(name);
          resultMessage.value += `文件夹 "${name}" 已存在\n`;
        } catch {
          // 不存在则创建
          currentDir = await currentDir.getDirectoryHandle(name, { create: true });
          resultMessage.value += `成功创建文件夹 "${name}"\n`;
        }
      }

      // 创建文件
      const fileName = file.fileName;
      let fileHandle: FileSystemFileHandle;
      try {
        fileHandle = await currentDir.getFileHandle(fileName);
        resultMessage.value += `，文件 "${fileName}" 已存在\n`;
      } catch {
        fileHandle = await currentDir.getFileHandle(fileName, { create: true });
        const writable = await fileHandle.createWritable();
        await writable.write(file.content);
        await writable.close();
        resultMessage.value += `，成功创建文件 "${fileName}"\n`;
      }
    } catch (error) {
      console.error('操作失败:', error);
      resultMessage.value = '操作失败，请查看控制台日志';
    }

    console.log("-----------",file.fileName);
  }

}


const handleGeneratorAndReview = () => {
  console.log("==",vo.value);
  api.generator(vo.value).then(res=>{
    if(apiUtil.isSuccessed(res)){
      codeContent.value = res.data;
    }
  })
}

const handleDownZip = () =>{
  api.download(vo.value.userTempPath);
}

const codeContent = ref<CodeContentVO>(new CodeContentVO());

const handleCheckboxChanged = (items: string[]) => {
  if (!items) {
    return;
  }

  if (!stepActive.value.includes("editConfig")) {
    let tempArray = stepActive.value;
    tempArray.push("editConfig");
    stepActive.value = tempArray;
  }
  let array = [];
  array.push(columns[0]);
  if (items.includes("java")) {
    array.push(columns[1]);
  }
  if (items.includes("vue")) {
    array.push(columns[2]);
    array.push(columns[3]);
  }
  if (items.includes("menu")) {
    menuConfigFlag.value = null;
  }else {
    menuConfigFlag.value = "disabled";
    if (stepActive.value.includes("configMenu")) {
      let tempArray = stepActive.value;
      let index = tempArray.indexOf("configMenu");
      if (index > -1) {
        tempArray.splice(index, 1);
      }
      stepActive.value = tempArray;
    }
  }
  newColumns.value = array;
}
</script>


<template>
  <main class="page-main">
    <div>

      <a-collapse v-model:activeKey="stepActive">
        <a-collapse-panel key="selectTable" header="选择数据表">

          <a-form :model="vo" :label-col="{ span: 3 }">
            <a-form-item name="tableName" label="数据表">
              <a-select v-model:value="vo.tableName" :options="tableList"
                        @change="handleQueryTables(vo.tableName)"></a-select>
            </a-form-item>
            <a-form-item name="tableName" label="要生成的内容">
              <a-checkbox-group @change="handleCheckboxChanged" v-model:value="vo.generatorItems"
                                :options="checkboxOptions"/>
            </a-form-item>
          </a-form>
        </a-collapse-panel>
        <a-collapse-panel key="editConfig" header="修改代码生成器配置">
          <a-table :columns="newColumns"
                   :data-source="vo.list"
                   :pagination="false"
                   :scroll="{ y: 420 }"
          >
            <!-- isShow 列：显示为 a-switch -->
            <template #bodyCell="{ column, record }">
              <template v-if="column.key === 'required'">
                <a-switch v-model:checked="record.required" disabled/>
              </template>

              <template v-if="column.key === 'isTableColumn'">
                <a-switch v-model:checked="record.isTableColumn"/>
              </template>
              <template v-if="column.key === 'columnTitle'">
                <a-input v-if="record.isTableColumn" v-model:value="record.columnTitle"/>
                <div v-else></div>
              </template>

              <template v-if="column.key === 'isFormData'">
                <a-switch v-model:checked="record.isFormData"/>
              </template>
              <template v-if="column.key === 'formNotNull'">
                <a-switch v-if="record.isFormData" v-model:checked="record.formNotNull"/>
                <div v-else></div>
              </template>

            </template>

          </a-table>
        </a-collapse-panel>
        <a-collapse-panel key="configMenu" header="配置菜单" :collapsible="menuConfigFlag">
          <a-form :model="vo" :label-col="{ span: 3 }">
            <a-form-item label="父级菜单">
              <a-select :options="groupTree" v-model:value="vo.parentMenuId"></a-select>
            </a-form-item>
            <a-form-item label="菜单名称">
              <a-input v-model:value="vo.menuName"></a-input>
            </a-form-item>
            <a-form-item label="菜单图标">
              <icon-selector
                  :icon-name="vo.iconName"
                  @changed="handleIconChanged"
                  :key="new Date().getTime()"
              />
            </a-form-item>
          </a-form>
        </a-collapse-panel>
        <a-collapse-panel key="previewCode" header="生成代码" >
          <div class="margin-bottom-20">
            <a-button type="primary" @click="handleGeneratorAndReview">生成&预览</a-button>
            <a-button type="primary" class="margin-left-20" @click="handleDownZip">打包下载</a-button>
            <a-button type="primary" class="margin-left-20" @click="createAll">全部执行</a-button>
          </div>

          <a-row :gutter="16">
            <a-col :span="18">
              <a-form :model="vo" :label-col="{ span: 3 }">
                <a-form-item v-if="vo.generatorItems && vo.generatorItems.includes('vue')" label="前端代码路径">
                  <a-button @click="selectFolder('vue')">项目src路径，如：/projectName/src</a-button>
                  <span class="margin-left-20 bolder">{{vuePath}}</span>
                </a-form-item>
                <a-form-item v-if="vo.generatorItems && vo.generatorItems.includes('java')" label="后端代码路径">
                  <a-button @click="selectFolder('java')">项目包路径，如：/projectName/src/main/java/com/example/demo</a-button>
                  <span class="margin-left-20 bolder">{{javaPath}}</span>
                </a-form-item>
                <a-form-item v-if="vo.generatorItems && vo.generatorItems.includes('java')" label="Java包路径">
                  <a-input v-model:value="vo.packageName" placeholder="请输入Java项目包名，如：com.coder4j.platform"></a-input>
                </a-form-item>
              </a-form>

              <a-tabs >
                <a-tab-pane v-if="vo.generatorItems && vo.generatorItems.includes('menu')" key="table" tab="SQL脚本">
                  <div>
                    <div class="text-right margin-bottom-20">
                      <a-button type="primary" class="margin-left-20">执行SQL</a-button>
                    </div>
                    <a-tabs>
                      <a-tab-pane v-for="(item,index) in codeContent.sqlFiles" :key="item.fileName"  :tab="item.title">
                        <MdPreview :editorId="'sql'+index" :modelValue="item.markdownContent" autoFoldThreshold="10000" />
                      </a-tab-pane>
                    </a-tabs>
                  </div>
                </a-tab-pane>
                <a-tab-pane v-if="vo.generatorItems && vo.generatorItems.includes('java')" key="java" tab="后端代码" force-render>
                  <a-tabs>
                    <a-tab-pane v-for="(item,index) in codeContent.javaFiles" :key="item.fileName"  :tab="item.title">
                      <MdPreview :editorId="'java'+index" v-model="item.markdownContent" autoFoldThreshold="10000" />
                    </a-tab-pane>
                  </a-tabs>
                </a-tab-pane>
                <a-tab-pane v-if="vo.generatorItems && vo.generatorItems.includes('vue')" key="vue" tab="前端代码">
                  <a-tabs>
                    <a-tab-pane v-for="(item,index) in codeContent.vueFiles" :key="item.fileName"  :tab="item.title">
                      <MdPreview :editorId="'vue'+index" :modelValue="item.markdownContent" autoFoldThreshold="10000" />
                    </a-tab-pane>
                  </a-tabs>
                </a-tab-pane>
              </a-tabs>
            </a-col>
            <a-col :span="6">
              <a-steps
                  v-if="codeContent && codeContent.logs"
                  direction="vertical"
                  size="small"
                  :current="codeContent.logs.length"
                  :items="codeContent.logs"
              >
              </a-steps>
            </a-col>
          </a-row>

        </a-collapse-panel>
      </a-collapse>
    </div>
  </main>
</template>


<style scoped>
.page-main {
  padding: 20px;
}
</style>
